package com.itheima.demo7executorService;

import java.util.concurrent.*;
/**使用给定的初始参数创建一个新 ThreadPoolExecutor 的。
 * <p>形参:
 * <p>corePoolSize – 要保留在池中的线程数，即使它们处于空闲状态.         正式工
 * <p>maximumPoolSize – 池中允许的最大线程数                          最多工人数量
 * <p>keepAliveTime – 当线程数大于内核数时，这是多余的空闲线程在终止之前等待新任务的最长时间。      临时工空闲多久被开除
 * <p>unit – 参数的时间 keepAliveTime 单位                             时间的单位
 * <p>workQueue ― 用于在执行任务之前保留任务的队列。此队列将仅        任务队列  客人排队的地方
 * <p>Runnable 保存该方法提交 execute 的任务。
 * <p>threadFactory – 执行器创建新线程时使用的工厂                    线程工厂  负责招聘的hr
 * <p>handler – 由于达到线程边界和队列容量而阻止执行时要使用的处理程序         拒绝策略
 */
public class ExecutorServiceDemo1 {
    public static void main(String[] args) {
        // 目标：创建线程池对象来使用。
        // 1、使用线程池的实现类ThreadPoolExecutor声明七个参数来创建线程池对象。
        ExecutorService pool = new ThreadPoolExecutor(
                3, // 核心线程数（正式工）
                5, // 最大线程数（最多工人数量）
                10, // 临时工空闲时间（秒）
                TimeUnit.SECONDS, // 时间单位
                new ArrayBlockingQueue<>(3), // 任务队列大小为3
                Executors.defaultThreadFactory(), // 默认线程工厂
                new ThreadPoolExecutor.AbortPolicy() // 拒绝策略：抛出异常并丢弃任务，默认策略
        );

        // 2、使用线程池处理任务！看会不会复用线程？
        Runnable target = new MyRunnable();
        pool.execute(target); // 提交第1个任务 创建第1个线程 自动启动线程处理这个任务
        pool.execute(target); // 提交第2个任务 创建第2个线程 自动启动线程处理这个任务
        pool.execute(target); // 提交第2个任务 创建第3个线程 自动启动线程处理这个任务
        pool.execute(target);
        pool.execute(target);
        pool.execute(target);
        pool.execute(target); // 到了临时线程的创建时机了
        pool.execute(target); // 到了临时线程的创建时机了
        pool.execute(target); // 到了任务拒绝策略了，忙不过来  核心线程都在忙,任务队列满了,临时线程也满了,拒绝策略!

        // 3、关闭线程池 ：一般不关闭线程池。
        // pool.shutdown(); // 等所有任务执行完毕后再关闭线程池！
//        pool.shutdownNow(); // 立即关闭，不管任务是否执行完毕！


   /*   任务拒绝策略:
        AbortPolicy: 抛出 RejectedExecutionException 异常并丢弃任务，是默认策略。
        DiscardPolicy: 丢弃任务但不抛出异常，不推荐使用。                        (不管了,直接丢)
        DiscardOldestPolicy: 丢弃队列中最旧的任务，然后把当前任务加入队列。
        CallerRunsPolicy: 由调用者线程直接执行任务，绕过线程池。                   (老板亲自来服务)
        */

    }

}
